#pragma once

#include <unordered_map>
#include <string>

namespace rpc
{
#define KEY_METHOD          "method"
#define KEY_PARAMS          "parameters"
#define KEY_TOPIC_NAME     "topic_name"
#define KEY_TOPIC_MSG       "topic_message"
#define KEY_OPTYPE          "operation_type"
#define KEY_HOST            "host"
#define KEY_HOST_IP         "ip"
#define KEY_HOST_PORT       "port"
#define KEY_RCODE           "response_code"
#define KEY_RES             "result"

    enum class MSG_TYPE // 消息类型
    {
        REQ_RPC = 0,
        RSP_RPC,
        REQ_TOPIC,
        RSP_TOPIC,
        REQ_SERVICE,
        RSP_SERVICE
    };

    enum class RCODE // 响应状态码
    {
        RCODE_OK = 0,
        RCODE_PARSE_FAILED,
        RCODE_ERROR_MSGTYPE,
        RCODE_INVALID_MSG,
        RCODE_DISCONNECTED,
        RCODE_INVALID_PARAM,
        RCODE_NOT_FOUND_SERVICE,
        RCODE_INVALID_OPERATION,
        RCODE_NOT_FOUND_TOPIC,
        RCODE_INTERNAL_ERROR
    };

    static std::string ERR_REASON(rpc::RCODE rcode)
    {
        static const std::unordered_map<rpc::RCODE, std::string> rcode_hash{
            {RCODE::RCODE_OK, "ok"},
            {RCODE::RCODE_PARSE_FAILED, "parse failed"},
            {RCODE::RCODE_ERROR_MSGTYPE, "message type error"},
            {RCODE::RCODE_INVALID_MSG, "invalild message"},
            {RCODE::RCODE_DISCONNECTED, "disconnected"},
            {RCODE::RCODE_INVALID_PARAM, "invalid parameters"},
            {RCODE::RCODE_NOT_FOUND_SERVICE, "not found service"},
            {RCODE::RCODE_INVALID_OPERATION, "invalid operation"},
            {RCODE::RCODE_NOT_FOUND_TOPIC, "not found topic"}};

        auto it = rcode_hash.find(rcode);
        if (it == rcode_hash.end())
        {
            return std::string("unknown error");
        }

        return it->second;
    }

    enum class REQ_TYPE
    {
        REQ_ASYNC = 0,
        REQ_CALLBACK
    };

    enum class TOPIC_OP_TYPE // 主题操作类型
    {
        TOPIC_CREATE = 0,
        TOPIC_REMOVE,
        TOPIC_SUBSCRIBE,
        TOPIC_CANCEL,
        TOPIC_PUBLISH
    };

    enum class SERVICE_OP_TYPE // 服务操作类型
    {
        SERVICE_REGISTER = 0,
        SERVICE_DISCOVERY,
        SERVICE_ONLINE,
        SERVICE_OFFLINE,
        SERVICE_UNKNOWN
    };
}